{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e94344a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "from torch.utils.data import DataLoader\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "\n",
    "\n",
    "import numpy as np  \n",
    "from PIL import Image\n",
    "import torchvision\n",
    "import torchvision.transforms.functional as F2\n",
    "from torchmetrics import StructuralSimilarityIndexMeasure as SSIM\n",
    "\n",
    "\n",
    "import os\n",
    "os.environ['KMP_DUPLICATE_LIB_OK']='True'\n",
    "from pylab import *\n",
    "mpl.rcParams['font.sans-serif'] = ['SimHei'] \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a88bd04a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sat Apr 15 10:46:36 2023       \n",
      "+-----------------------------------------------------------------------------+\n",
      "| NVIDIA-SMI 451.67       Driver Version: 451.67       CUDA Version: 11.0     |\n",
      "|-------------------------------+----------------------+----------------------+\n",
      "| GPU  Name            TCC/WDDM | Bus-Id        Disp.A | Volatile Uncorr. ECC |\n",
      "| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |\n",
      "|===============================+======================+======================|\n",
      "|   0  GeForce GTX 1650   WDDM  | 00000000:01:00.0 Off |                  N/A |\n",
      "| N/A   75C    P8     2W /  N/A |    134MiB /  4096MiB |      0%      Default |\n",
      "+-------------------------------+----------------------+----------------------+\n",
      "                                                                               \n",
      "+-----------------------------------------------------------------------------+\n",
      "| Processes:                                                                  |\n",
      "|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |\n",
      "|        ID   ID                                                   Usage      |\n",
      "|=============================================================================|\n",
      "|    0   N/A  N/A      2400    C+G   ...ysdiag\\bin\\HipsDaemon.exe    N/A      |\n",
      "+-----------------------------------------------------------------------------+\n"
     ]
    }
   ],
   "source": [
    "!nvidia-smi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "db35bc9e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch._C.Generator at 0x1c1006c95d0>"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n_epochs = 3\n",
    "batch_size_train = 32\n",
    "batch_size_test = 1000\n",
    "learning_rate = 0.01\n",
    "momentum = 0.5\n",
    "log_interval = 10\n",
    "random_seed = 1\n",
    "torch.manual_seed(random_seed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "421ac9de",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "train_loader = torch.utils.data.DataLoader(\n",
    "    torchvision.datasets.MNIST('./data/', train=True, download=False,\n",
    "                               transform=torchvision.transforms.Compose([\n",
    "                                   torchvision.transforms.ToTensor(),\n",
    "                                   torchvision.transforms.Normalize(\n",
    "                                       (0.1307,), (0.3081,))\n",
    "                               ])),\n",
    "    batch_size=batch_size_train, shuffle=True)\n",
    "test_loader = torch.utils.data.DataLoader(\n",
    "    torchvision.datasets.MNIST('./data/', train=False, download=False,\n",
    "                               transform=torchvision.transforms.Compose([\n",
    "                                   torchvision.transforms.ToTensor(),\n",
    "                                   torchvision.transforms.Normalize(\n",
    "                                       (0.1307,), (0.3081,))\n",
    "                               ])),\n",
    "    batch_size=batch_size_test, shuffle=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "522ad88c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([32])\n",
      "tensor([4, 8, 8, 6, 7, 1, 0, 7, 1, 8, 7, 6, 4, 9, 1, 5, 3, 2, 6, 8, 8, 6, 9, 4,\n",
      "        6, 0, 4, 2, 6, 7, 0, 5])\n",
      "torch.Size([32, 1, 28, 28])\n"
     ]
    }
   ],
   "source": [
    "examples = enumerate(train_loader)\n",
    "batch_idx,(example_data, example_targets) = next(examples)\n",
    "print(example_targets.size())\n",
    "print(example_targets)\n",
    "print(example_data.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "39d232dc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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l19+We3bt1dMTEypdT/++KMGDRqkp59+Wk2aNNGIESP02GOP6Z133im1bunSpWU6fX7zzTcrIyND6enp3trMmTPVsWNH2/uCGZkxc3tmzvbtt99q1apVevnll8u1H/wXmTFze2bee+89ff7554qJidGuXbt08OBBzZ8/X48++qj+/Oc/296fbUaYmT9/viHJ2Llzp2EYhnHhhRcakgxJRmZmpnddkyZNjOjoaOPLL7807eO1114zIiIijB07dpSqeTweY/fu3YZhGIYkY+XKlaUe16RJE+8xunbtasTFxRlZWVne3994443GvffeaxiGYTz++ONGYmKikZ+f7/1927Ztja5du9p+zpmZmYYk48iRI6bfDRs2zJBkvPjii6bf7d6925DkfU5nWD03q5phGMakSZMMScbChQu9teeee85o1qyZ7efhy+LFi42EhATjf/7nf4y3337bGDZsmFGlShVj8eLFATtGOCMzpYVCZs42cuRIIy0trUL2Ha7ITGmhkJm+ffsaUVFRxvr16721cePGGZJK/f9RRQm7t0GrVq0qScrLy5MkLV++XBs3blS9evVMa++55x7Lqz02bNigRo0a6eKLL/bW0tLSZBiGNmzY4PPYJSUlpX4eOHCgGjZs6P35ggsuUGFhoSRpx44datOmTam/Hrp06eLPU7StdevW3g/nn89vn4M/6tWrp5tuusn789nPMxAmTpyoKVOmaMqUKbr55ps1d+5c3XrrrZowYULAjhHOyIyZ2zNzRlFRkRYsWKDbbrst4PsOZ2TGzO2Z2bFjh7p37+69oEKSHnjgAUnSxo0bA3YcX8JuWGvWrJkkaefOnZJOv4BSU1NVUFBgWuvrslzjNx9m9+d3RUVFOnjwYKnaRRdd5HM/JSUlioyMLFX77c+B0qFDB0VE+PdSyMrKsr3/cz3PQNixY4fp7YXU1FTLzyvAPjJj5vbMnLF8+XIdPXpUAwYMqJTjhQsyY+b2zCQkJJT6DKIk70Vs0dHRFXpsKQyHtdatW6tevXp69913vbW9e/fq8OHDfu/jiiuuUFZWljeIkrRixQp5PB7v1B0ZGakTJ054f79o0SLTlH+uUDRr1kybN28u9Zi1a9f63WMgREWd/kjj2c9jwYIFlmtjYmJKffD1bBUV/jOSkpK8n2k4Y9myZWrQoEGFHjdckBn/uSUzZ7z77rvq2LGj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\n",
      "text/plain": [
       "<Figure size 640x480 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure()\n",
    "for i in range(6,12):\n",
    "    plt.subplot(2,3,i-5)\n",
    "    plt.tight_layout()\n",
    "    plt.imshow(example_data[i][0], cmap='gray', interpolation='none')\n",
    "    plt.title(\"Ground Truth: {}\".format(example_targets[i]))\n",
    "    plt.xlabel('这是行')\n",
    "    plt.ylabel('这是列')\n",
    "    plt.xticks([1])\n",
    "    plt.yticks([2])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "167fcfbe",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)#12*12\n",
    "        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)#4*4\n",
    "        self.conv2_drop = nn.Dropout2d()\n",
    "        self.fc1 = nn.Linear(320, 400)\n",
    "        self.fc2 = nn.Linear(400, 10)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        x = F.relu(F.max_pool2d(self.conv1(x), 2))\n",
    "        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))\n",
    "        x = x.view(-1, 320)   \n",
    "        x=self.fc1(x)\n",
    "        self.feature = x.view(-1,20,20)\n",
    "        x = F.relu(x)\n",
    "        x = F.dropout(x, training=self.training)\n",
    "        x = self.fc2(x)\n",
    "      \n",
    "        return F.log_softmax(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "69a54c75",
   "metadata": {},
   "outputs": [],
   "source": [
    "device = \"cuda\" if torch.cuda.is_available() else \"cpu\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "id": "9344e1d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "network = Net().to(device)\n",
    "optimizer = optim.SGD(network.parameters(), lr=learning_rate, momentum=momentum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "id": "6cd027fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_losses = []\n",
    "train_counter = []\n",
    "test_losses = []\n",
    "test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)]\n",
    "feature_all = []\n",
    "label_all = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "40a781f0",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Administrator\\AppData\\Local\\Temp\\ipykernel_12964\\262562906.py:20: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.\n",
      "  return F.log_softmax(x)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch: 1 [288/60000 (0%)]\tLoss: 0.163190\n",
      "Train Epoch: 1 [608/60000 (1%)]\tLoss: 0.152233\n",
      "Train Epoch: 1 [928/60000 (2%)]\tLoss: 0.246862\n",
      "Train Epoch: 1 [1248/60000 (2%)]\tLoss: 0.062722\n",
      "Train Epoch: 1 [1568/60000 (3%)]\tLoss: 0.308410\n",
      "Train Epoch: 1 [1888/60000 (3%)]\tLoss: 0.081097\n",
      "Train Epoch: 1 [2208/60000 (4%)]\tLoss: 0.526877\n",
      "Train Epoch: 1 [2528/60000 (4%)]\tLoss: 0.184062\n",
      "Train Epoch: 1 [2848/60000 (5%)]\tLoss: 0.090351\n",
      "Train Epoch: 1 [3168/60000 (5%)]\tLoss: 0.055634\n",
      "Train Epoch: 1 [3488/60000 (6%)]\tLoss: 0.041625\n",
      "Train Epoch: 1 [3808/60000 (6%)]\tLoss: 0.151613\n",
      "Train Epoch: 1 [4128/60000 (7%)]\tLoss: 0.298189\n",
      "Train Epoch: 1 [4448/60000 (7%)]\tLoss: 0.113243\n",
      "Train Epoch: 1 [4768/60000 (8%)]\tLoss: 0.018331\n",
      "Train Epoch: 1 [5088/60000 (8%)]\tLoss: 0.196284\n",
      "Train Epoch: 1 [5408/60000 (9%)]\tLoss: 0.094228\n",
      "Train Epoch: 1 [5728/60000 (10%)]\tLoss: 0.402563\n",
      "Train Epoch: 1 [6048/60000 (10%)]\tLoss: 0.234350\n",
      "Train Epoch: 1 [6368/60000 (11%)]\tLoss: 0.062914\n",
      "Train Epoch: 1 [6688/60000 (11%)]\tLoss: 0.181306\n",
      "Train Epoch: 1 [7008/60000 (12%)]\tLoss: 0.098650\n",
      "Train Epoch: 1 [7328/60000 (12%)]\tLoss: 0.043333\n",
      "Train Epoch: 1 [7648/60000 (13%)]\tLoss: 0.261237\n",
      "Train Epoch: 1 [7968/60000 (13%)]\tLoss: 0.075870\n",
      "Train Epoch: 1 [8288/60000 (14%)]\tLoss: 0.122984\n",
      "Train Epoch: 1 [8608/60000 (14%)]\tLoss: 0.060059\n",
      "Train Epoch: 1 [8928/60000 (15%)]\tLoss: 0.109636\n",
      "Train Epoch: 1 [9248/60000 (15%)]\tLoss: 0.224274\n",
      "Train Epoch: 1 [9568/60000 (16%)]\tLoss: 0.200644\n",
      "Train Epoch: 1 [9888/60000 (16%)]\tLoss: 0.100052\n",
      "Train Epoch: 1 [10208/60000 (17%)]\tLoss: 0.206625\n",
      "Train Epoch: 1 [10528/60000 (18%)]\tLoss: 0.122069\n",
      "Train Epoch: 1 [10848/60000 (18%)]\tLoss: 0.049303\n",
      "Train Epoch: 1 [11168/60000 (19%)]\tLoss: 0.045309\n",
      "Train Epoch: 1 [11488/60000 (19%)]\tLoss: 0.091380\n",
      "Train Epoch: 1 [11808/60000 (20%)]\tLoss: 0.036762\n",
      "Train Epoch: 1 [12128/60000 (20%)]\tLoss: 0.110886\n",
      "Train Epoch: 1 [12448/60000 (21%)]\tLoss: 0.424725\n",
      "Train Epoch: 1 [12768/60000 (21%)]\tLoss: 0.220387\n",
      "Train Epoch: 1 [13088/60000 (22%)]\tLoss: 0.137069\n",
      "Train Epoch: 1 [13408/60000 (22%)]\tLoss: 0.384629\n",
      "Train Epoch: 1 [13728/60000 (23%)]\tLoss: 0.292516\n",
      "Train Epoch: 1 [14048/60000 (23%)]\tLoss: 0.088957\n",
      "Train Epoch: 1 [14368/60000 (24%)]\tLoss: 0.032984\n",
      "Train Epoch: 1 [14688/60000 (24%)]\tLoss: 0.025740\n",
      "Train Epoch: 1 [15008/60000 (25%)]\tLoss: 0.149490\n",
      "Train Epoch: 1 [15328/60000 (26%)]\tLoss: 0.037128\n",
      "Train Epoch: 1 [15648/60000 (26%)]\tLoss: 0.126987\n",
      "Train Epoch: 1 [15968/60000 (27%)]\tLoss: 0.188550\n",
      "Train Epoch: 1 [16288/60000 (27%)]\tLoss: 0.140509\n",
      "Train Epoch: 1 [16608/60000 (28%)]\tLoss: 0.280434\n",
      "Train Epoch: 1 [16928/60000 (28%)]\tLoss: 0.072428\n",
      "Train Epoch: 1 [17248/60000 (29%)]\tLoss: 0.091252\n",
      "Train Epoch: 1 [17568/60000 (29%)]\tLoss: 0.202578\n",
      "Train Epoch: 1 [17888/60000 (30%)]\tLoss: 0.028848\n",
      "Train Epoch: 1 [18208/60000 (30%)]\tLoss: 0.099181\n",
      "Train Epoch: 1 [18528/60000 (31%)]\tLoss: 0.039255\n",
      "Train Epoch: 1 [18848/60000 (31%)]\tLoss: 0.088981\n",
      "Train Epoch: 1 [19168/60000 (32%)]\tLoss: 0.131281\n",
      "Train Epoch: 1 [19488/60000 (32%)]\tLoss: 0.091728\n",
      "Train Epoch: 1 [19808/60000 (33%)]\tLoss: 0.062530\n",
      "Train Epoch: 1 [20128/60000 (34%)]\tLoss: 0.099080\n",
      "Train Epoch: 1 [20448/60000 (34%)]\tLoss: 0.116540\n",
      "Train Epoch: 1 [20768/60000 (35%)]\tLoss: 0.028806\n",
      "Train Epoch: 1 [21088/60000 (35%)]\tLoss: 0.330299\n",
      "Train Epoch: 1 [21408/60000 (36%)]\tLoss: 0.096767\n",
      "Train Epoch: 1 [21728/60000 (36%)]\tLoss: 0.232403\n",
      "Train Epoch: 1 [22048/60000 (37%)]\tLoss: 0.177975\n",
      "Train Epoch: 1 [22368/60000 (37%)]\tLoss: 0.056677\n",
      "Train Epoch: 1 [22688/60000 (38%)]\tLoss: 0.034285\n",
      "Train Epoch: 1 [23008/60000 (38%)]\tLoss: 0.324853\n",
      "Train Epoch: 1 [23328/60000 (39%)]\tLoss: 0.215674\n",
      "Train Epoch: 1 [23648/60000 (39%)]\tLoss: 0.034326\n",
      "Train Epoch: 1 [23968/60000 (40%)]\tLoss: 0.036887\n",
      "Train Epoch: 1 [24288/60000 (40%)]\tLoss: 0.085400\n",
      "Train Epoch: 1 [24608/60000 (41%)]\tLoss: 0.128423\n",
      "Train Epoch: 1 [24928/60000 (42%)]\tLoss: 0.079286\n",
      "Train Epoch: 1 [25248/60000 (42%)]\tLoss: 0.031470\n",
      "Train Epoch: 1 [25568/60000 (43%)]\tLoss: 0.374287\n",
      "Train Epoch: 1 [25888/60000 (43%)]\tLoss: 0.152027\n",
      "Train Epoch: 1 [26208/60000 (44%)]\tLoss: 0.127231\n",
      "Train Epoch: 1 [26528/60000 (44%)]\tLoss: 0.036605\n",
      "Train Epoch: 1 [26848/60000 (45%)]\tLoss: 0.321793\n",
      "Train Epoch: 1 [27168/60000 (45%)]\tLoss: 0.310341\n",
      "Train Epoch: 1 [27488/60000 (46%)]\tLoss: 0.070686\n",
      "Train Epoch: 1 [27808/60000 (46%)]\tLoss: 0.068126\n",
      "Train Epoch: 1 [28128/60000 (47%)]\tLoss: 0.075507\n",
      "Train Epoch: 1 [28448/60000 (47%)]\tLoss: 0.083774\n",
      "Train Epoch: 1 [28768/60000 (48%)]\tLoss: 0.070510\n",
      "Train Epoch: 1 [29088/60000 (48%)]\tLoss: 0.264288\n",
      "Train Epoch: 1 [29408/60000 (49%)]\tLoss: 0.225992\n",
      "Train Epoch: 1 [29728/60000 (50%)]\tLoss: 0.125603\n",
      "Train Epoch: 1 [30048/60000 (50%)]\tLoss: 0.130346\n",
      "Train Epoch: 1 [30368/60000 (51%)]\tLoss: 0.240084\n",
      "Train Epoch: 1 [30688/60000 (51%)]\tLoss: 0.152224\n",
      "Train Epoch: 1 [31008/60000 (52%)]\tLoss: 0.035354\n",
      "Train Epoch: 1 [31328/60000 (52%)]\tLoss: 0.132335\n",
      "Train Epoch: 1 [31648/60000 (53%)]\tLoss: 0.154326\n",
      "Train Epoch: 1 [31968/60000 (53%)]\tLoss: 0.138219\n",
      "Train Epoch: 1 [32288/60000 (54%)]\tLoss: 0.143834\n",
      "Train Epoch: 1 [32608/60000 (54%)]\tLoss: 0.128769\n",
      "Train Epoch: 1 [32928/60000 (55%)]\tLoss: 0.043551\n",
      "Train Epoch: 1 [33248/60000 (55%)]\tLoss: 0.035899\n",
      "Train Epoch: 1 [33568/60000 (56%)]\tLoss: 0.253345\n",
      "Train Epoch: 1 [33888/60000 (56%)]\tLoss: 0.168889\n",
      "Train Epoch: 1 [34208/60000 (57%)]\tLoss: 0.398855\n",
      "Train Epoch: 1 [34528/60000 (58%)]\tLoss: 0.180517\n",
      "Train Epoch: 1 [34848/60000 (58%)]\tLoss: 0.147852\n",
      "Train Epoch: 1 [35168/60000 (59%)]\tLoss: 0.374691\n",
      "Train Epoch: 1 [35488/60000 (59%)]\tLoss: 0.047118\n",
      "Train Epoch: 1 [35808/60000 (60%)]\tLoss: 0.061473\n",
      "Train Epoch: 1 [36128/60000 (60%)]\tLoss: 0.072963\n",
      "Train Epoch: 1 [36448/60000 (61%)]\tLoss: 0.249609\n",
      "Train Epoch: 1 [36768/60000 (61%)]\tLoss: 0.115041\n",
      "Train Epoch: 1 [37088/60000 (62%)]\tLoss: 0.087822\n",
      "Train Epoch: 1 [37408/60000 (62%)]\tLoss: 0.169645\n",
      "Train Epoch: 1 [37728/60000 (63%)]\tLoss: 0.072598\n",
      "Train Epoch: 1 [38048/60000 (63%)]\tLoss: 0.446015\n",
      "Train Epoch: 1 [38368/60000 (64%)]\tLoss: 0.073785\n",
      "Train Epoch: 1 [38688/60000 (64%)]\tLoss: 0.078672\n",
      "Train Epoch: 1 [39008/60000 (65%)]\tLoss: 0.157378\n",
      "Train Epoch: 1 [39328/60000 (66%)]\tLoss: 0.136296\n",
      "Train Epoch: 1 [39648/60000 (66%)]\tLoss: 0.106871\n",
      "Train Epoch: 1 [39968/60000 (67%)]\tLoss: 0.092186\n",
      "Train Epoch: 1 [40288/60000 (67%)]\tLoss: 0.163267\n",
      "Train Epoch: 1 [40608/60000 (68%)]\tLoss: 0.146029\n",
      "Train Epoch: 1 [40928/60000 (68%)]\tLoss: 0.240067\n",
      "Train Epoch: 1 [41248/60000 (69%)]\tLoss: 0.188592\n",
      "Train Epoch: 1 [41568/60000 (69%)]\tLoss: 0.028381\n",
      "Train Epoch: 1 [41888/60000 (70%)]\tLoss: 0.137792\n",
      "Train Epoch: 1 [42208/60000 (70%)]\tLoss: 0.063042\n",
      "Train Epoch: 1 [42528/60000 (71%)]\tLoss: 0.199486\n",
      "Train Epoch: 1 [42848/60000 (71%)]\tLoss: 0.125007\n",
      "Train Epoch: 1 [43168/60000 (72%)]\tLoss: 0.075902\n",
      "Train Epoch: 1 [43488/60000 (72%)]\tLoss: 0.030418\n",
      "Train Epoch: 1 [43808/60000 (73%)]\tLoss: 0.149987\n",
      "Train Epoch: 1 [44128/60000 (74%)]\tLoss: 0.127309\n",
      "Train Epoch: 1 [44448/60000 (74%)]\tLoss: 0.236224\n",
      "Train Epoch: 1 [44768/60000 (75%)]\tLoss: 0.035709\n",
      "Train Epoch: 1 [45088/60000 (75%)]\tLoss: 0.076291\n",
      "Train Epoch: 1 [45408/60000 (76%)]\tLoss: 0.037194\n",
      "Train Epoch: 1 [45728/60000 (76%)]\tLoss: 0.217716\n",
      "Train Epoch: 1 [46048/60000 (77%)]\tLoss: 0.123087\n",
      "Train Epoch: 1 [46368/60000 (77%)]\tLoss: 0.273501\n",
      "Train Epoch: 1 [46688/60000 (78%)]\tLoss: 0.045170\n",
      "Train Epoch: 1 [47008/60000 (78%)]\tLoss: 0.297183\n",
      "Train Epoch: 1 [47328/60000 (79%)]\tLoss: 0.091436\n",
      "Train Epoch: 1 [47648/60000 (79%)]\tLoss: 0.106010\n",
      "Train Epoch: 1 [47968/60000 (80%)]\tLoss: 0.308541\n",
      "Train Epoch: 1 [48288/60000 (80%)]\tLoss: 0.375054\n",
      "Train Epoch: 1 [48608/60000 (81%)]\tLoss: 0.187324\n",
      "Train Epoch: 1 [48928/60000 (82%)]\tLoss: 0.041462\n",
      "Train Epoch: 1 [49248/60000 (82%)]\tLoss: 0.032631\n",
      "Train Epoch: 1 [49568/60000 (83%)]\tLoss: 0.026099\n",
      "Train Epoch: 1 [49888/60000 (83%)]\tLoss: 0.170105\n",
      "Train Epoch: 1 [50208/60000 (84%)]\tLoss: 0.041043\n",
      "Train Epoch: 1 [50528/60000 (84%)]\tLoss: 0.032050\n",
      "Train Epoch: 1 [50848/60000 (85%)]\tLoss: 0.226979\n",
      "Train Epoch: 1 [51168/60000 (85%)]\tLoss: 0.124163\n",
      "Train Epoch: 1 [51488/60000 (86%)]\tLoss: 0.023949\n",
      "Train Epoch: 1 [51808/60000 (86%)]\tLoss: 0.129973\n",
      "Train Epoch: 1 [52128/60000 (87%)]\tLoss: 0.081271\n",
      "Train Epoch: 1 [52448/60000 (87%)]\tLoss: 0.102550\n",
      "Train Epoch: 1 [52768/60000 (88%)]\tLoss: 0.291327\n",
      "Train Epoch: 1 [53088/60000 (88%)]\tLoss: 0.443769\n",
      "Train Epoch: 1 [53408/60000 (89%)]\tLoss: 0.042265\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch: 1 [53728/60000 (90%)]\tLoss: 0.045325\n",
      "Train Epoch: 1 [54048/60000 (90%)]\tLoss: 0.168295\n",
      "Train Epoch: 1 [54368/60000 (91%)]\tLoss: 0.034116\n",
      "Train Epoch: 1 [54688/60000 (91%)]\tLoss: 0.317517\n",
      "Train Epoch: 1 [55008/60000 (92%)]\tLoss: 0.097564\n",
      "Train Epoch: 1 [55328/60000 (92%)]\tLoss: 0.083105\n",
      "Train Epoch: 1 [55648/60000 (93%)]\tLoss: 0.243238\n",
      "Train Epoch: 1 [55968/60000 (93%)]\tLoss: 0.009609\n",
      "Train Epoch: 1 [56288/60000 (94%)]\tLoss: 0.169641\n",
      "Train Epoch: 1 [56608/60000 (94%)]\tLoss: 0.258606\n",
      "Train Epoch: 1 [56928/60000 (95%)]\tLoss: 0.100046\n",
      "Train Epoch: 1 [57248/60000 (95%)]\tLoss: 0.042696\n",
      "Train Epoch: 1 [57568/60000 (96%)]\tLoss: 0.042977\n",
      "Train Epoch: 1 [57888/60000 (96%)]\tLoss: 0.215062\n",
      "Train Epoch: 1 [58208/60000 (97%)]\tLoss: 0.132676\n",
      "Train Epoch: 1 [58528/60000 (98%)]\tLoss: 0.129173\n",
      "Train Epoch: 1 [58848/60000 (98%)]\tLoss: 0.114168\n",
      "Train Epoch: 1 [59168/60000 (99%)]\tLoss: 0.132056\n",
      "Train Epoch: 1 [59488/60000 (99%)]\tLoss: 0.091652\n",
      "Train Epoch: 1 [59808/60000 (100%)]\tLoss: 0.086053\n",
      "torch.Size([1875, 32, 20, 20]) torch.Size([1875, 32])\n"
     ]
    }
   ],
   "source": [
    "def train(epoch):\n",
    "    global feature_all,label_all\n",
    "    network.train()\n",
    "    for batch_idx, (data, target) in enumerate(train_loader):\n",
    "        data = data.to(device)\n",
    "        target = target.to(device)\n",
    "        label_all.append(target)\n",
    "        optimizer.zero_grad()\n",
    "        output = network(data)\n",
    "        feature_all.append(network.feature)\n",
    "        loss = F.nll_loss(output, target)\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        if batch_idx % log_interval == 9:\n",
    "            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n",
    "                epoch, batch_idx * len(data), len(train_loader.dataset),\n",
    "                       100. * batch_idx / len(train_loader), loss.item()))\n",
    "            train_losses.append(loss.item())\n",
    "            train_counter.append(\n",
    "                (batch_idx * 64) + ((epoch - 1) * len(train_loader.dataset)))\n",
    "            torch.save(network.state_dict(), './model.pth')\n",
    "            torch.save(optimizer.state_dict(), './optimizer.pth')\n",
    "    #feature_all= torch.tensor([item.cpu().detach().numpy() for item in feature_all]).cuda()\n",
    "    #label_all= torch.tensor([item.cpu().detach().numpy() for item in label_all]).cuda()\n",
    "    feature_all = torch.stack(feature_all)\n",
    "    label_all = torch.stack(label_all)\n",
    "    feature_all.view(-1,20,20)\n",
    "    label_all.view(-1,32,1)\n",
    "    print(feature_all.shape,label_all.shape)\n",
    "train(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "id": "f034b39c",
   "metadata": {},
   "outputs": [],
   "source": [
    "feature_all=feature_all.reshape(1875*32,20,20)\n",
    "label_all = label_all.reshape(1875*32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "id": "7fcac990",
   "metadata": {},
   "outputs": [],
   "source": [
    "t_feature = []\n",
    "t_label = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "id": "2b0a61b4",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Administrator\\AppData\\Local\\Temp\\ipykernel_12964\\262562906.py:20: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.\n",
      "  return F.log_softmax(x)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([1000, 20, 20]) torch.Size([1000])\n",
      "torch.Size([2000, 20, 20]) torch.Size([2000])\n",
      "torch.Size([3000, 20, 20]) torch.Size([3000])\n",
      "torch.Size([4000, 20, 20]) torch.Size([4000])\n",
      "torch.Size([5000, 20, 20]) torch.Size([5000])\n",
      "torch.Size([6000, 20, 20]) torch.Size([6000])\n",
      "torch.Size([7000, 20, 20]) torch.Size([7000])\n",
      "torch.Size([8000, 20, 20]) torch.Size([8000])\n",
      "torch.Size([9000, 20, 20]) torch.Size([9000])\n",
      "torch.Size([10000, 20, 20]) torch.Size([10000])\n",
      "\n",
      "Test set: Avg. loss: 0.0637, Accuracy: 9809/10000 (98%)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def test():\n",
    "    global t_feature,t_label\n",
    "    t_feature=torch.tensor(t_feature).cuda()\n",
    "    t_label = torch.tensor(t_label).cuda()\n",
    "    network.eval()\n",
    "    test_loss = 0\n",
    "    correct = 0\n",
    "    with torch.no_grad():\n",
    "        \n",
    "        \n",
    "        \n",
    "        for i,(data, target) in enumerate(test_loader):\n",
    "            data=data.to(device)\n",
    "            target = target.to(device)\n",
    "            #t_label.append(target)\n",
    "            output = network(data)\n",
    "            #t_feature.append(network.feature)\n",
    "            test_loss += F.nll_loss(output, target, size_average=False).item()\n",
    "            pred = output.data.max(1, keepdim=True)[1]    \n",
    "            \n",
    "            t_feature=torch.cat([t_feature,network.feature],dim =0)\n",
    "            t_label=torch.cat([t_label,target],dim =0)\n",
    "            print(t_feature.shape,t_label.shape)\n",
    "            \n",
    "            correct += pred.eq(target.data.view_as(pred)).sum()\n",
    "    test_loss /= len(test_loader.dataset)\n",
    "    test_losses.append(test_loss)\n",
    "    print('\\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n",
    "        test_loss, correct, len(test_loader.dataset),\n",
    "        100. * correct / len(test_loader.dataset)))\n",
    " \n",
    "test()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "id": "6f3a6d91",
   "metadata": {},
   "outputs": [],
   "source": [
    "feuturee=torch.cat([feature_all,t_feature],dim=0)\n",
    "labell = torch.cat([label_all,t_label],dim = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "id": "e1a55971",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([70000, 20, 20]) torch.Size([70000])\n"
     ]
    }
   ],
   "source": [
    "print(feuturee.shape,labell.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "id": "53a2cb62",
   "metadata": {},
   "outputs": [],
   "source": [
    "adj = torch.zeros(70000,70000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "id": "7f5f84bc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([1, 1, 20, 20]) torch.Size([1, 1, 20, 20])\n"
     ]
    }
   ],
   "source": [
    "\n",
    "for i in range(70000):\n",
    "    img1_tensor = feuturee[i].unsqueeze(0).unsqueeze(0)#Torch.Tensor\n",
    "    for j in range(i,70000):\n",
    "        img2_tensor = feature[j].unsqueeze(0).unsqueeze(0)\n",
    "        ssim = SSIM(data_range=1.0, win_size=3, win_sigma=1.5, \n",
    "        k1=0.01, k2=0.03, eps=1e-8, reduction='elementwise_mean').to(device)\n",
    "        value = ssim(img1_tensor, img2_tensor)\n",
    "        if value>0.3:\n",
    "            adj[i][j] = 1\n",
    "adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "024eec4c",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Administrator\\AppData\\Local\\Temp\\ipykernel_10148\\250604375.py:18: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.\n",
      "  return F.log_softmax(x)\n",
      "C:\\Users\\Administrator\\AppData\\Local\\Temp\\ipykernel_10148\\3491794677.py:14: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.\n",
      "  output2 = F.log_softmax(network.fc2(F.dropout(F.relu(network.fc1(feature)),training = True)))\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "\n",
      "Test set: Avg. loss: 0.1637, Accuracy: 9534/10000 (95%)\n",
      "\n",
      "Train Epoch: 1 [576/60000 (1%)]\tLoss: 0.409301\n",
      "Train Epoch: 1 [1216/60000 (2%)]\tLoss: 0.312388\n",
      "Train Epoch: 1 [1856/60000 (3%)]\tLoss: 0.454057\n",
      "Train Epoch: 1 [2496/60000 (4%)]\tLoss: 0.461006\n",
      "Train Epoch: 1 [3136/60000 (5%)]\tLoss: 0.187806\n",
      "Train Epoch: 1 [3776/60000 (6%)]\tLoss: 0.284820\n",
      "Train Epoch: 1 [4416/60000 (7%)]\tLoss: 0.406830\n",
      "Train Epoch: 1 [5056/60000 (8%)]\tLoss: 0.511117\n",
      "Train Epoch: 1 [5696/60000 (9%)]\tLoss: 0.502116\n",
      "Train Epoch: 1 [6336/60000 (11%)]\tLoss: 0.501021\n",
      "Train Epoch: 1 [6976/60000 (12%)]\tLoss: 0.515035\n",
      "Train Epoch: 1 [7616/60000 (13%)]\tLoss: 0.326172\n",
      "Train Epoch: 1 [8256/60000 (14%)]\tLoss: 0.400410\n",
      "Train Epoch: 1 [8896/60000 (15%)]\tLoss: 0.416741\n",
      "Train Epoch: 1 [9536/60000 (16%)]\tLoss: 0.341575\n",
      "Train Epoch: 1 [10176/60000 (17%)]\tLoss: 0.453976\n",
      "Train Epoch: 1 [10816/60000 (18%)]\tLoss: 0.384898\n",
      "Train Epoch: 1 [11456/60000 (19%)]\tLoss: 0.394519\n",
      "Train Epoch: 1 [12096/60000 (20%)]\tLoss: 0.269627\n",
      "Train Epoch: 1 [12736/60000 (21%)]\tLoss: 0.344383\n",
      "Train Epoch: 1 [13376/60000 (22%)]\tLoss: 0.303589\n",
      "Train Epoch: 1 [14016/60000 (23%)]\tLoss: 0.592836\n",
      "Train Epoch: 1 [14656/60000 (24%)]\tLoss: 0.441280\n",
      "Train Epoch: 1 [15296/60000 (25%)]\tLoss: 0.277347\n",
      "Train Epoch: 1 [15936/60000 (27%)]\tLoss: 0.283216\n",
      "Train Epoch: 1 [16576/60000 (28%)]\tLoss: 0.410538\n",
      "Train Epoch: 1 [17216/60000 (29%)]\tLoss: 0.440758\n",
      "Train Epoch: 1 [17856/60000 (30%)]\tLoss: 0.506244\n",
      "Train Epoch: 1 [18496/60000 (31%)]\tLoss: 0.291932\n",
      "Train Epoch: 1 [19136/60000 (32%)]\tLoss: 0.454631\n",
      "Train Epoch: 1 [19776/60000 (33%)]\tLoss: 0.504634\n",
      "Train Epoch: 1 [20416/60000 (34%)]\tLoss: 0.245111\n",
      "Train Epoch: 1 [21056/60000 (35%)]\tLoss: 0.398466\n",
      "Train Epoch: 1 [21696/60000 (36%)]\tLoss: 0.235061\n",
      "Train Epoch: 1 [22336/60000 (37%)]\tLoss: 0.412158\n",
      "Train Epoch: 1 [22976/60000 (38%)]\tLoss: 0.392918\n",
      "Train Epoch: 1 [23616/60000 (39%)]\tLoss: 0.454268\n",
      "Train Epoch: 1 [24256/60000 (40%)]\tLoss: 0.452504\n",
      "Train Epoch: 1 [24896/60000 (41%)]\tLoss: 0.340276\n",
      "Train Epoch: 1 [25536/60000 (43%)]\tLoss: 0.501804\n",
      "Train Epoch: 1 [26176/60000 (44%)]\tLoss: 0.457916\n",
      "Train Epoch: 1 [26816/60000 (45%)]\tLoss: 0.375092\n",
      "Train Epoch: 1 [27456/60000 (46%)]\tLoss: 0.554099\n",
      "Train Epoch: 1 [28096/60000 (47%)]\tLoss: 0.402781\n",
      "Train Epoch: 1 [28736/60000 (48%)]\tLoss: 0.408505\n",
      "Train Epoch: 1 [29376/60000 (49%)]\tLoss: 0.435195\n",
      "Train Epoch: 1 [30016/60000 (50%)]\tLoss: 0.389518\n",
      "Train Epoch: 1 [30656/60000 (51%)]\tLoss: 0.324629\n",
      "Train Epoch: 1 [31296/60000 (52%)]\tLoss: 0.363388\n",
      "Train Epoch: 1 [31936/60000 (53%)]\tLoss: 0.380673\n",
      "Train Epoch: 1 [32576/60000 (54%)]\tLoss: 0.205261\n",
      "Train Epoch: 1 [33216/60000 (55%)]\tLoss: 0.364974\n",
      "Train Epoch: 1 [33856/60000 (56%)]\tLoss: 0.530483\n",
      "Train Epoch: 1 [34496/60000 (57%)]\tLoss: 0.296503\n",
      "Train Epoch: 1 [35136/60000 (59%)]\tLoss: 0.355200\n",
      "Train Epoch: 1 [35776/60000 (60%)]\tLoss: 0.293381\n",
      "Train Epoch: 1 [36416/60000 (61%)]\tLoss: 0.351900\n",
      "Train Epoch: 1 [37056/60000 (62%)]\tLoss: 0.421785\n",
      "Train Epoch: 1 [37696/60000 (63%)]\tLoss: 0.411783\n",
      "Train Epoch: 1 [38336/60000 (64%)]\tLoss: 0.213768\n",
      "Train Epoch: 1 [38976/60000 (65%)]\tLoss: 0.518518\n",
      "Train Epoch: 1 [39616/60000 (66%)]\tLoss: 0.321864\n",
      "Train Epoch: 1 [40256/60000 (67%)]\tLoss: 0.190086\n",
      "Train Epoch: 1 [40896/60000 (68%)]\tLoss: 0.222148\n",
      "Train Epoch: 1 [41536/60000 (69%)]\tLoss: 0.431690\n",
      "Train Epoch: 1 [42176/60000 (70%)]\tLoss: 0.246382\n",
      "Train Epoch: 1 [42816/60000 (71%)]\tLoss: 0.424167\n",
      "Train Epoch: 1 [43456/60000 (72%)]\tLoss: 0.471801\n",
      "Train Epoch: 1 [44096/60000 (73%)]\tLoss: 0.297927\n",
      "Train Epoch: 1 [44736/60000 (75%)]\tLoss: 0.498351\n",
      "Train Epoch: 1 [45376/60000 (76%)]\tLoss: 0.293797\n",
      "Train Epoch: 1 [46016/60000 (77%)]\tLoss: 0.166574\n",
      "Train Epoch: 1 [46656/60000 (78%)]\tLoss: 0.176962\n",
      "Train Epoch: 1 [47296/60000 (79%)]\tLoss: 0.180394\n",
      "Train Epoch: 1 [47936/60000 (80%)]\tLoss: 0.354834\n",
      "Train Epoch: 1 [48576/60000 (81%)]\tLoss: 0.271589\n",
      "Train Epoch: 1 [49216/60000 (82%)]\tLoss: 0.296919\n",
      "Train Epoch: 1 [49856/60000 (83%)]\tLoss: 0.230947\n",
      "Train Epoch: 1 [50496/60000 (84%)]\tLoss: 0.193865\n",
      "Train Epoch: 1 [51136/60000 (85%)]\tLoss: 0.168445\n",
      "Train Epoch: 1 [51776/60000 (86%)]\tLoss: 0.281159\n",
      "Train Epoch: 1 [52416/60000 (87%)]\tLoss: 0.211003\n",
      "Train Epoch: 1 [53056/60000 (88%)]\tLoss: 0.414931\n",
      "Train Epoch: 1 [53696/60000 (89%)]\tLoss: 0.223465\n",
      "Train Epoch: 1 [54336/60000 (91%)]\tLoss: 0.253221\n",
      "Train Epoch: 1 [54976/60000 (92%)]\tLoss: 0.237940\n",
      "Train Epoch: 1 [55616/60000 (93%)]\tLoss: 0.304899\n",
      "Train Epoch: 1 [56256/60000 (94%)]\tLoss: 0.444288\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch: 1 [56896/60000 (95%)]\tLoss: 0.270147\n",
      "Train Epoch: 1 [57536/60000 (96%)]\tLoss: 0.324555\n",
      "Train Epoch: 1 [58176/60000 (97%)]\tLoss: 0.529499\n",
      "Train Epoch: 1 [58816/60000 (98%)]\tLoss: 0.257855\n",
      "Train Epoch: 1 [59456/60000 (99%)]\tLoss: 0.402746\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "\n",
      "Test set: Avg. loss: 0.1067, Accuracy: 9672/10000 (97%)\n",
      "\n",
      "Train Epoch: 2 [576/60000 (1%)]\tLoss: 0.318052\n",
      "Train Epoch: 2 [1216/60000 (2%)]\tLoss: 0.522669\n",
      "Train Epoch: 2 [1856/60000 (3%)]\tLoss: 0.250449\n",
      "Train Epoch: 2 [2496/60000 (4%)]\tLoss: 0.287330\n",
      "Train Epoch: 2 [3136/60000 (5%)]\tLoss: 0.159312\n",
      "Train Epoch: 2 [3776/60000 (6%)]\tLoss: 0.261730\n",
      "Train Epoch: 2 [4416/60000 (7%)]\tLoss: 0.246878\n",
      "Train Epoch: 2 [5056/60000 (8%)]\tLoss: 0.256958\n",
      "Train Epoch: 2 [5696/60000 (9%)]\tLoss: 0.391163\n",
      "Train Epoch: 2 [6336/60000 (11%)]\tLoss: 0.172150\n",
      "Train Epoch: 2 [6976/60000 (12%)]\tLoss: 0.190569\n",
      "Train Epoch: 2 [7616/60000 (13%)]\tLoss: 0.341943\n",
      "Train Epoch: 2 [8256/60000 (14%)]\tLoss: 0.346760\n",
      "Train Epoch: 2 [8896/60000 (15%)]\tLoss: 0.218087\n",
      "Train Epoch: 2 [9536/60000 (16%)]\tLoss: 0.188173\n",
      "Train Epoch: 2 [10176/60000 (17%)]\tLoss: 0.451281\n",
      "Train Epoch: 2 [10816/60000 (18%)]\tLoss: 0.355180\n",
      "Train Epoch: 2 [11456/60000 (19%)]\tLoss: 0.288202\n",
      "Train Epoch: 2 [12096/60000 (20%)]\tLoss: 0.288870\n",
      "Train Epoch: 2 [12736/60000 (21%)]\tLoss: 0.180660\n",
      "Train Epoch: 2 [13376/60000 (22%)]\tLoss: 0.336658\n",
      "Train Epoch: 2 [14016/60000 (23%)]\tLoss: 0.339235\n",
      "Train Epoch: 2 [14656/60000 (24%)]\tLoss: 0.660429\n",
      "Train Epoch: 2 [15296/60000 (25%)]\tLoss: 0.360677\n",
      "Train Epoch: 2 [15936/60000 (27%)]\tLoss: 0.251598\n",
      "Train Epoch: 2 [16576/60000 (28%)]\tLoss: 0.160571\n",
      "Train Epoch: 2 [17216/60000 (29%)]\tLoss: 0.457959\n",
      "Train Epoch: 2 [17856/60000 (30%)]\tLoss: 0.674883\n",
      "Train Epoch: 2 [18496/60000 (31%)]\tLoss: 0.337204\n",
      "Train Epoch: 2 [19136/60000 (32%)]\tLoss: 0.342649\n",
      "Train Epoch: 2 [19776/60000 (33%)]\tLoss: 0.255546\n",
      "Train Epoch: 2 [20416/60000 (34%)]\tLoss: 0.203629\n",
      "Train Epoch: 2 [21056/60000 (35%)]\tLoss: 0.214825\n",
      "Train Epoch: 2 [21696/60000 (36%)]\tLoss: 0.313594\n",
      "Train Epoch: 2 [22336/60000 (37%)]\tLoss: 0.315548\n",
      "Train Epoch: 2 [22976/60000 (38%)]\tLoss: 0.260677\n",
      "Train Epoch: 2 [23616/60000 (39%)]\tLoss: 0.215292\n",
      "Train Epoch: 2 [24256/60000 (40%)]\tLoss: 0.315456\n",
      "Train Epoch: 2 [24896/60000 (41%)]\tLoss: 0.176872\n",
      "Train Epoch: 2 [25536/60000 (43%)]\tLoss: 0.189407\n",
      "Train Epoch: 2 [26176/60000 (44%)]\tLoss: 0.267337\n",
      "Train Epoch: 2 [26816/60000 (45%)]\tLoss: 0.328718\n",
      "Train Epoch: 2 [27456/60000 (46%)]\tLoss: 0.265829\n",
      "Train Epoch: 2 [28096/60000 (47%)]\tLoss: 0.253413\n",
      "Train Epoch: 2 [28736/60000 (48%)]\tLoss: 0.225238\n",
      "Train Epoch: 2 [29376/60000 (49%)]\tLoss: 0.354727\n",
      "Train Epoch: 2 [30016/60000 (50%)]\tLoss: 0.342151\n",
      "Train Epoch: 2 [30656/60000 (51%)]\tLoss: 0.369999\n",
      "Train Epoch: 2 [31296/60000 (52%)]\tLoss: 0.154910\n",
      "Train Epoch: 2 [31936/60000 (53%)]\tLoss: 0.179963\n",
      "Train Epoch: 2 [32576/60000 (54%)]\tLoss: 0.167610\n",
      "Train Epoch: 2 [33216/60000 (55%)]\tLoss: 0.343532\n",
      "Train Epoch: 2 [33856/60000 (56%)]\tLoss: 0.430022\n",
      "Train Epoch: 2 [34496/60000 (57%)]\tLoss: 0.206650\n",
      "Train Epoch: 2 [35136/60000 (59%)]\tLoss: 0.420938\n",
      "Train Epoch: 2 [35776/60000 (60%)]\tLoss: 0.300370\n",
      "Train Epoch: 2 [36416/60000 (61%)]\tLoss: 0.230006\n",
      "Train Epoch: 2 [37056/60000 (62%)]\tLoss: 0.339736\n",
      "Train Epoch: 2 [37696/60000 (63%)]\tLoss: 0.375211\n",
      "Train Epoch: 2 [38336/60000 (64%)]\tLoss: 0.219882\n",
      "Train Epoch: 2 [38976/60000 (65%)]\tLoss: 0.240468\n",
      "Train Epoch: 2 [39616/60000 (66%)]\tLoss: 0.292001\n",
      "Train Epoch: 2 [40256/60000 (67%)]\tLoss: 0.104823\n",
      "Train Epoch: 2 [40896/60000 (68%)]\tLoss: 0.224201\n",
      "Train Epoch: 2 [41536/60000 (69%)]\tLoss: 0.237382\n",
      "Train Epoch: 2 [42176/60000 (70%)]\tLoss: 0.130411\n",
      "Train Epoch: 2 [42816/60000 (71%)]\tLoss: 0.335545\n",
      "Train Epoch: 2 [43456/60000 (72%)]\tLoss: 0.063971\n",
      "Train Epoch: 2 [44096/60000 (73%)]\tLoss: 0.225667\n",
      "Train Epoch: 2 [44736/60000 (75%)]\tLoss: 0.298880\n",
      "Train Epoch: 2 [45376/60000 (76%)]\tLoss: 0.404334\n",
      "Train Epoch: 2 [46016/60000 (77%)]\tLoss: 0.263136\n",
      "Train Epoch: 2 [46656/60000 (78%)]\tLoss: 0.252361\n",
      "Train Epoch: 2 [47296/60000 (79%)]\tLoss: 0.265224\n",
      "Train Epoch: 2 [47936/60000 (80%)]\tLoss: 0.380160\n",
      "Train Epoch: 2 [48576/60000 (81%)]\tLoss: 0.199001\n",
      "Train Epoch: 2 [49216/60000 (82%)]\tLoss: 0.273314\n",
      "Train Epoch: 2 [49856/60000 (83%)]\tLoss: 0.206887\n",
      "Train Epoch: 2 [50496/60000 (84%)]\tLoss: 0.381692\n",
      "Train Epoch: 2 [51136/60000 (85%)]\tLoss: 0.290529\n",
      "Train Epoch: 2 [51776/60000 (86%)]\tLoss: 0.459275\n",
      "Train Epoch: 2 [52416/60000 (87%)]\tLoss: 0.203631\n",
      "Train Epoch: 2 [53056/60000 (88%)]\tLoss: 0.388615\n",
      "Train Epoch: 2 [53696/60000 (89%)]\tLoss: 0.214818\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch: 2 [54336/60000 (91%)]\tLoss: 0.510691\n",
      "Train Epoch: 2 [54976/60000 (92%)]\tLoss: 0.326439\n",
      "Train Epoch: 2 [55616/60000 (93%)]\tLoss: 0.087345\n",
      "Train Epoch: 2 [56256/60000 (94%)]\tLoss: 0.154745\n",
      "Train Epoch: 2 [56896/60000 (95%)]\tLoss: 0.375896\n",
      "Train Epoch: 2 [57536/60000 (96%)]\tLoss: 0.276286\n",
      "Train Epoch: 2 [58176/60000 (97%)]\tLoss: 0.233178\n",
      "Train Epoch: 2 [58816/60000 (98%)]\tLoss: 0.187839\n",
      "Train Epoch: 2 [59456/60000 (99%)]\tLoss: 0.492913\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "\n",
      "Test set: Avg. loss: 0.0849, Accuracy: 9735/10000 (97%)\n",
      "\n",
      "Train Epoch: 3 [576/60000 (1%)]\tLoss: 0.205141\n",
      "Train Epoch: 3 [1216/60000 (2%)]\tLoss: 0.176931\n",
      "Train Epoch: 3 [1856/60000 (3%)]\tLoss: 0.389670\n",
      "Train Epoch: 3 [2496/60000 (4%)]\tLoss: 0.366920\n",
      "Train Epoch: 3 [3136/60000 (5%)]\tLoss: 0.177122\n",
      "Train Epoch: 3 [3776/60000 (6%)]\tLoss: 0.217191\n",
      "Train Epoch: 3 [4416/60000 (7%)]\tLoss: 0.414746\n",
      "Train Epoch: 3 [5056/60000 (8%)]\tLoss: 0.203727\n",
      "Train Epoch: 3 [5696/60000 (9%)]\tLoss: 0.238482\n",
      "Train Epoch: 3 [6336/60000 (11%)]\tLoss: 0.283071\n",
      "Train Epoch: 3 [6976/60000 (12%)]\tLoss: 0.229958\n",
      "Train Epoch: 3 [7616/60000 (13%)]\tLoss: 0.253466\n",
      "Train Epoch: 3 [8256/60000 (14%)]\tLoss: 0.207769\n",
      "Train Epoch: 3 [8896/60000 (15%)]\tLoss: 0.241519\n",
      "Train Epoch: 3 [9536/60000 (16%)]\tLoss: 0.342772\n",
      "Train Epoch: 3 [10176/60000 (17%)]\tLoss: 0.143255\n",
      "Train Epoch: 3 [10816/60000 (18%)]\tLoss: 0.158277\n",
      "Train Epoch: 3 [11456/60000 (19%)]\tLoss: 0.148400\n",
      "Train Epoch: 3 [12096/60000 (20%)]\tLoss: 0.344613\n",
      "Train Epoch: 3 [12736/60000 (21%)]\tLoss: 0.227603\n",
      "Train Epoch: 3 [13376/60000 (22%)]\tLoss: 0.119211\n",
      "Train Epoch: 3 [14016/60000 (23%)]\tLoss: 0.258600\n",
      "Train Epoch: 3 [14656/60000 (24%)]\tLoss: 0.137713\n",
      "Train Epoch: 3 [15296/60000 (25%)]\tLoss: 0.368131\n",
      "Train Epoch: 3 [15936/60000 (27%)]\tLoss: 0.125932\n",
      "Train Epoch: 3 [16576/60000 (28%)]\tLoss: 0.220956\n",
      "Train Epoch: 3 [17216/60000 (29%)]\tLoss: 0.199605\n",
      "Train Epoch: 3 [17856/60000 (30%)]\tLoss: 0.280898\n",
      "Train Epoch: 3 [18496/60000 (31%)]\tLoss: 0.224297\n",
      "Train Epoch: 3 [19136/60000 (32%)]\tLoss: 0.535596\n",
      "Train Epoch: 3 [19776/60000 (33%)]\tLoss: 0.137175\n",
      "Train Epoch: 3 [20416/60000 (34%)]\tLoss: 0.214814\n",
      "Train Epoch: 3 [21056/60000 (35%)]\tLoss: 0.276994\n",
      "Train Epoch: 3 [21696/60000 (36%)]\tLoss: 0.431072\n",
      "Train Epoch: 3 [22336/60000 (37%)]\tLoss: 0.354751\n",
      "Train Epoch: 3 [22976/60000 (38%)]\tLoss: 0.285217\n",
      "Train Epoch: 3 [23616/60000 (39%)]\tLoss: 0.341181\n",
      "Train Epoch: 3 [24256/60000 (40%)]\tLoss: 0.176465\n",
      "Train Epoch: 3 [24896/60000 (41%)]\tLoss: 0.448878\n",
      "Train Epoch: 3 [25536/60000 (43%)]\tLoss: 0.372488\n",
      "Train Epoch: 3 [26176/60000 (44%)]\tLoss: 0.254420\n",
      "Train Epoch: 3 [26816/60000 (45%)]\tLoss: 0.144019\n",
      "Train Epoch: 3 [27456/60000 (46%)]\tLoss: 0.250247\n",
      "Train Epoch: 3 [28096/60000 (47%)]\tLoss: 0.290044\n",
      "Train Epoch: 3 [28736/60000 (48%)]\tLoss: 0.242819\n",
      "Train Epoch: 3 [29376/60000 (49%)]\tLoss: 0.175827\n",
      "Train Epoch: 3 [30016/60000 (50%)]\tLoss: 0.389778\n",
      "Train Epoch: 3 [30656/60000 (51%)]\tLoss: 0.316260\n",
      "Train Epoch: 3 [31296/60000 (52%)]\tLoss: 0.124579\n",
      "Train Epoch: 3 [31936/60000 (53%)]\tLoss: 0.136980\n",
      "Train Epoch: 3 [32576/60000 (54%)]\tLoss: 0.210264\n",
      "Train Epoch: 3 [33216/60000 (55%)]\tLoss: 0.283120\n",
      "Train Epoch: 3 [33856/60000 (56%)]\tLoss: 0.307506\n",
      "Train Epoch: 3 [34496/60000 (57%)]\tLoss: 0.203341\n",
      "Train Epoch: 3 [35136/60000 (59%)]\tLoss: 0.266085\n",
      "Train Epoch: 3 [35776/60000 (60%)]\tLoss: 0.354661\n",
      "Train Epoch: 3 [36416/60000 (61%)]\tLoss: 0.214130\n",
      "Train Epoch: 3 [37056/60000 (62%)]\tLoss: 0.237632\n",
      "Train Epoch: 3 [37696/60000 (63%)]\tLoss: 0.389400\n",
      "Train Epoch: 3 [38336/60000 (64%)]\tLoss: 0.200630\n",
      "Train Epoch: 3 [38976/60000 (65%)]\tLoss: 0.233783\n",
      "Train Epoch: 3 [39616/60000 (66%)]\tLoss: 0.168504\n",
      "Train Epoch: 3 [40256/60000 (67%)]\tLoss: 0.287502\n",
      "Train Epoch: 3 [40896/60000 (68%)]\tLoss: 0.196441\n",
      "Train Epoch: 3 [41536/60000 (69%)]\tLoss: 0.097130\n",
      "Train Epoch: 3 [42176/60000 (70%)]\tLoss: 0.281967\n",
      "Train Epoch: 3 [42816/60000 (71%)]\tLoss: 0.218641\n",
      "Train Epoch: 3 [43456/60000 (72%)]\tLoss: 0.212036\n",
      "Train Epoch: 3 [44096/60000 (73%)]\tLoss: 0.354809\n",
      "Train Epoch: 3 [44736/60000 (75%)]\tLoss: 0.377863\n",
      "Train Epoch: 3 [45376/60000 (76%)]\tLoss: 0.181877\n",
      "Train Epoch: 3 [46016/60000 (77%)]\tLoss: 0.320353\n",
      "Train Epoch: 3 [46656/60000 (78%)]\tLoss: 0.152332\n",
      "Train Epoch: 3 [47296/60000 (79%)]\tLoss: 0.365763\n",
      "Train Epoch: 3 [47936/60000 (80%)]\tLoss: 0.323045\n",
      "Train Epoch: 3 [48576/60000 (81%)]\tLoss: 0.240136\n",
      "Train Epoch: 3 [49216/60000 (82%)]\tLoss: 0.347806\n",
      "Train Epoch: 3 [49856/60000 (83%)]\tLoss: 0.178928\n",
      "Train Epoch: 3 [50496/60000 (84%)]\tLoss: 0.161972\n",
      "Train Epoch: 3 [51136/60000 (85%)]\tLoss: 0.270151\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch: 3 [51776/60000 (86%)]\tLoss: 0.256879\n",
      "Train Epoch: 3 [52416/60000 (87%)]\tLoss: 0.335244\n",
      "Train Epoch: 3 [53056/60000 (88%)]\tLoss: 0.176690\n",
      "Train Epoch: 3 [53696/60000 (89%)]\tLoss: 0.148945\n",
      "Train Epoch: 3 [54336/60000 (91%)]\tLoss: 0.188560\n",
      "Train Epoch: 3 [54976/60000 (92%)]\tLoss: 0.255967\n",
      "Train Epoch: 3 [55616/60000 (93%)]\tLoss: 0.333551\n",
      "Train Epoch: 3 [56256/60000 (94%)]\tLoss: 0.091008\n",
      "Train Epoch: 3 [56896/60000 (95%)]\tLoss: 0.188122\n",
      "Train Epoch: 3 [57536/60000 (96%)]\tLoss: 0.123742\n",
      "Train Epoch: 3 [58176/60000 (97%)]\tLoss: 0.286237\n",
      "Train Epoch: 3 [58816/60000 (98%)]\tLoss: 0.144571\n",
      "Train Epoch: 3 [59456/60000 (99%)]\tLoss: 0.350039\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "\n",
      "Test set: Avg. loss: 0.0726, Accuracy: 9767/10000 (98%)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "test()  # 不加这个，后面画图就会报错：x and y must be the same size\n",
    "for epoch in range(1, n_epochs + 1):\n",
    "    train(epoch)\n",
    "    test()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "9d43c490",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Administrator\\AppData\\Local\\Temp\\ipykernel_10148\\760425996.py:16: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.\n",
      "  return F.log_softmax(x)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Test set: Avg. loss: 0.0808, Accuracy: 9749/10000 (97%)\n",
      "\n"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "x and y must be the same size",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "Cell \u001b[1;32mIn [14], line 4\u001b[0m\n\u001b[0;32m      2\u001b[0m fig \u001b[38;5;241m=\u001b[39m plt\u001b[38;5;241m.\u001b[39mfigure()\n\u001b[0;32m      3\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(train_counter, train_losses, color\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mblue\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m----> 4\u001b[0m \u001b[43mplt\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mscatter\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtest_counter\u001b[49m\u001b[43m,\u001b[49m\u001b[43mtest_losses\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcolor\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mred\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m      5\u001b[0m plt\u001b[38;5;241m.\u001b[39mlegend([\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mTrain Loss\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mTest Loss\u001b[39m\u001b[38;5;124m'\u001b[39m], loc\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mupper right\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m      6\u001b[0m plt\u001b[38;5;241m.\u001b[39mxlabel(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnumber of training examples seen\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
      "File \u001b[1;32mD:\\coding\\Anaconda3\\envs\\pytorch\\lib\\site-packages\\matplotlib\\pyplot.py:2790\u001b[0m, in \u001b[0;36mscatter\u001b[1;34m(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, data, **kwargs)\u001b[0m\n\u001b[0;32m   2785\u001b[0m \u001b[38;5;129m@_copy_docstring_and_deprecators\u001b[39m(Axes\u001b[38;5;241m.\u001b[39mscatter)\n\u001b[0;32m   2786\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mscatter\u001b[39m(\n\u001b[0;32m   2787\u001b[0m         x, y, s\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, c\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, marker\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, cmap\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, norm\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m   2788\u001b[0m         vmin\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, vmax\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, alpha\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, linewidths\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m,\n\u001b[0;32m   2789\u001b[0m         edgecolors\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, plotnonfinite\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, data\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m-> 2790\u001b[0m     __ret \u001b[38;5;241m=\u001b[39m gca()\u001b[38;5;241m.\u001b[39mscatter(\n\u001b[0;32m   2791\u001b[0m         x, y, s\u001b[38;5;241m=\u001b[39ms, c\u001b[38;5;241m=\u001b[39mc, marker\u001b[38;5;241m=\u001b[39mmarker, cmap\u001b[38;5;241m=\u001b[39mcmap, norm\u001b[38;5;241m=\u001b[39mnorm,\n\u001b[0;32m   2792\u001b[0m         vmin\u001b[38;5;241m=\u001b[39mvmin, vmax\u001b[38;5;241m=\u001b[39mvmax, alpha\u001b[38;5;241m=\u001b[39malpha, linewidths\u001b[38;5;241m=\u001b[39mlinewidths,\n\u001b[0;32m   2793\u001b[0m         edgecolors\u001b[38;5;241m=\u001b[39medgecolors, plotnonfinite\u001b[38;5;241m=\u001b[39mplotnonfinite,\n\u001b[0;32m   2794\u001b[0m         \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m({\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdata\u001b[39m\u001b[38;5;124m\"\u001b[39m: data} \u001b[38;5;28;01mif\u001b[39;00m data \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m {}), \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m   2795\u001b[0m     sci(__ret)\n\u001b[0;32m   2796\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m __ret\n",
      "File \u001b[1;32mD:\\coding\\Anaconda3\\envs\\pytorch\\lib\\site-packages\\matplotlib\\__init__.py:1423\u001b[0m, in \u001b[0;36m_preprocess_data.<locals>.inner\u001b[1;34m(ax, data, *args, **kwargs)\u001b[0m\n\u001b[0;32m   1420\u001b[0m \u001b[38;5;129m@functools\u001b[39m\u001b[38;5;241m.\u001b[39mwraps(func)\n\u001b[0;32m   1421\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21minner\u001b[39m(ax, \u001b[38;5;241m*\u001b[39margs, data\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m   1422\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m data \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m-> 1423\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m func(ax, \u001b[38;5;241m*\u001b[39m\u001b[38;5;28mmap\u001b[39m(sanitize_sequence, args), \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m   1425\u001b[0m     bound \u001b[38;5;241m=\u001b[39m new_sig\u001b[38;5;241m.\u001b[39mbind(ax, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m   1426\u001b[0m     auto_label \u001b[38;5;241m=\u001b[39m (bound\u001b[38;5;241m.\u001b[39marguments\u001b[38;5;241m.\u001b[39mget(label_namer)\n\u001b[0;32m   1427\u001b[0m                   \u001b[38;5;129;01mor\u001b[39;00m bound\u001b[38;5;241m.\u001b[39mkwargs\u001b[38;5;241m.\u001b[39mget(label_namer))\n",
      "File \u001b[1;32mD:\\coding\\Anaconda3\\envs\\pytorch\\lib\\site-packages\\matplotlib\\axes\\_axes.py:4520\u001b[0m, in \u001b[0;36mAxes.scatter\u001b[1;34m(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, **kwargs)\u001b[0m\n\u001b[0;32m   4518\u001b[0m y \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mma\u001b[38;5;241m.\u001b[39mravel(y)\n\u001b[0;32m   4519\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m x\u001b[38;5;241m.\u001b[39msize \u001b[38;5;241m!=\u001b[39m y\u001b[38;5;241m.\u001b[39msize:\n\u001b[1;32m-> 4520\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mx and y must be the same size\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m   4522\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m s \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m   4523\u001b[0m     s \u001b[38;5;241m=\u001b[39m (\u001b[38;5;241m20\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m mpl\u001b[38;5;241m.\u001b[39mrcParams[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m_internal.classic_mode\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;28;01melse\u001b[39;00m\n\u001b[0;32m   4524\u001b[0m          mpl\u001b[38;5;241m.\u001b[39mrcParams[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlines.markersize\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m \u001b[38;5;241m2.0\u001b[39m)\n",
      "\u001b[1;31mValueError\u001b[0m: x and y must be the same size"
     ]
    },
    {
     "data": {
      "image/png": "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X3zl4WvlypUJ+/mY44TISGbx1FNP4eyzz0ZZWRkKCgrw8ssvY/To0YjFYpg7dy7GjRsXt811112H22+/HT169MDIkSPx2muvoaysLNT+2trasGbNGvTq1QuxWCyVogbS2NiIoUOHYuXKlaisrMzKf+YLrDvrzrp3H1h31j3KujuOg6amJgwaNAgFBcEhqSkLEQBYt24d5syZg8MOOwy9e/cOtc3ChQuxevVqHHvssQljRDqCxsZGVFVVoaGhoVteoKw7696dYN1Zd9a9c5NSjIgyYMAAnHLKKSltM3r0aIwePTqd3RFCCCGki8JJ7wghhBASGd1SiJSWluLGG2/slsOEWXfWvbvBurPu3Y18q3taMSKEEEIIIdmgW1pECCGEENI5oBAhhBBCSGRQiBBCCCEkMihECCGEEBIZ3U6ILFiwAOPHj0dNTQ2uvvrq5DnwOyFPPvkkRowYgaKiIowbNw6LFi0CAFx++eWIxWLtr7322qt9m0T1fuWVVzBq1Cj06dMHd955p2tfjz76KPbYYw8MGjQIf/3rXzumggkIqmMu6jdt2jT0798fI0aMwIsvvpj7yiXg/vvvd9VbX/fffz+mTJni+u74449v3y6f675p0ybU1dVhxYoV7d919Hm+7rrrUFNTg7Fjx2LevHnZr2QAfnUPuu+BrnXv+9W9o+sX1fXvrXui+x5A17n3Q0/60gXYsWOHM3z4cOfiiy92li5d6px88snt8+bkC0uXLnVqamqcRx55xFm3bp3z1a9+1TniiCMcx3Gcww8/3JkxY4ZTX1/v1NfXO42NjY7jJK73hg0bnMrKSuemm25yPvjgA+fAAw90XnzxRcdxHGf+/PlOSUmJM336dGfevHnOXnvt5SxevDiain+GXx1zUb9///vfTo8ePZwnnnjCeeONN5y6ujpn06ZNkdW7paWlvc719fXOypUrnT59+jhLly51Bg4c6MyfP7/9t61bt+Z93Tdu3OgceuihDgBn+fLljuPk5jpOVNd7773X6d27t/Pqq686Tz75pDNq1CinpaUlkronuu8dp+vc+3517+j6RXX9+9U90X3vOE6Xufe7lRB5/PHHnZqaGmfbtm2O48iEfEceeWTEpUqNp59+2vnd737X/vnFF190ysrKnNbWVqeystJpamqK2yZRve+66y5n3333ddra2hzHcZwnnnjCOffccx3HcZzvfve7zqRJk9r/5+6773auu+66nNUtGUF1zEX9vvSlLzkXX3xx+29XXHGFM3369NxVLkV+9rOfORdddJGzatUqZ8CAAb7r5HPdP//5zzv33HOPq1Hu6PN8wAEHOLfcckv7b1/+8ped559/Pkc1NvjVPei+d5zg+8Jx8u/e96t7R9cvquvfr+5e9L53HKdL3fvdyjXz3nvv4bDDDkN5eTkAYOzYsVi4cGHEpUqNyZMn43/+53/aPy9ZsgQjR47E/Pnz0dbWhnHjxqGsrAwnnngiPvnkEwCJ6/3ee+9hwoQJ7RMKHnLIIZgzZ077bxMnTmzfl/1bFATVMRf162x1t9mxYwfuueceXHvttZg9ezZ2796NIUOGoKKiAmeddRbq6+sB5Hfdp0+fjssvv9z1XUeeZ8dxMH/+/EiOg1/dg+57IPi+APLv3vere0fXrzPV3ca+7wF0qXu/WwmRxsZG1NXVtX+OxWIoLCxsP3n5xs6dO3HHHXfgkksuwcKFC7HPPvvgwQcfxLx581BUVNTecCWqt/e3yspKrFmzxnc7+7coCKpjLurX2epu8/DDD+PQQw/F8OHDsXjxYhxwwAGYMWMG3nrrLSxfvhxTp04FkH79OkPd7f0rHXmet27dira2tkiOg1/dbez7Hgi+L4D8u/f96t7R9etMdbex73sAXereT2vSu3ylqKgoLuVtjx490NzcjJqamohKlT433ngjKioqcOGFF6K4uBjnnntu+2+/+c1vUFdXh8bGxoT19v6m3wPxx8v+LQrOPfdc3zqOGjUq6/XrbHW3uffee/HjH/8YADB16tT2xgcAbrvtNpx22mm49957u1zdc3EdB/1WVCRNY2c8DvZ9DwTfF13l3u/o+nWmutvY9z3Qte79bmURqa2txcaNG13fNTU1oaSkJKISpc+LL76IadOm4eGHH0ZxcXHc7/369UNbWxvWrl2bsN7e3+zjkei3zoDWccCAAVmvX2et+9KlS7F06VKccMIJvr/369cPmzdvRktLS5erey6u46DfysrKUFZW1umOQ7L7Huj6936u69cZ657svgfy+97vVkJk/PjxmDVrVvvn5cuXt5+0fGL58uU4++yzMW3aNIwePRoAcPXVV+Phhx9uX2fWrFkoKCjA0KFDE9bb+9vcuXMxePBgAPHHy/4tCoLqOGbMmKzXr7PVXfnb3/6GyZMnt3dCZ555Jl5//fX232fNmoX+/fujtLS0y9U9F9dxot8OPvjgTnUc/O57oOvf+x1dv85Ud8V73wNd7N7PeThsJ6K1tdXp27dv+/CuCy+80Jk8eXLEpUqN5uZmZ/To0c5FF13kNDU1tb8eeOABp66uzpk5c6bz7LPPOnvvvbdz/vnnO46TuN4bN250evTo4Tz//PPOzp07nRNPPNG57LLLHMeRCPSKigpn3rx5TlNTkzNu3Djn9ttvj6bijuM8+OCDvnXMRf2efPJJZ+DAgc6qVaucdevWOYMHD3YeffTRaCpucfTRRzv33Xdf++ef/OQnzsEHH+y89tprzuOPP+7079/f+fGPf+w4TteoOzyjJzryPN9zzz3O/vvv7zQ0NDhLlixxysvLnXfeeSeSugfd921tbYH3Ra6OWUfXvaPrF/X1D59RM9773nG61r3frYSI48iBLi8vd3r37u307dvXef/996MuUko88cQTDoC41/Lly51rrrnGqaqqcmpra53LL7+8fUy54ySu929/+1unuLjYqampcerq6px169a1/3bttdc6JSUlTmVlpXPQQQc5zc3NHVpfL0F1zHb92tranK997WtOWVmZU1ZW5kyePLl9KFxUNDc3OyUlJc6iRYvav9u5c6fzzW9+06moqHAGDBjg3HTTTU5ra2v77/led2+j3JHneceOHc7EiROdXr16OSUlJc63vvWtjqn0Z9h1T3TfO07wfeE4+Xnve897R9Yv6uvfW3e/+95xuta9H3OcPEwtmiHr1q3DnDlzcNhhh6F3795RF6fDSFTv5cuXY/HixTj66KPRs2dP128LFy7E6tWrceyxx0buK01ELur3n//8B9u2bcOxxx7bPhQu3+hqde/I89zW1oY33ngDpaWlOOSQQ3JXqRzDe7/rXP+pkC9175ZChBBCCCGdg24VrEoIIYSQzgWFCCGEEEIig0KEEEIIIZFBIUIIIYSQyKAQIYQQQkhkUIgQQgghJDIoRAghhBASGRQihBBCCIkMChFCCCGERMb/B0eAt5fm4Di0AAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test() \n",
    "fig = plt.figure()\n",
    "plt.plot(train_counter, train_losses, color='blue')\n",
    "plt.scatter(test_counter,test_losses, color='red')\n",
    "plt.legend(['Train Loss', 'Test Loss'], loc='upper right')\n",
    "plt.xlabel('number of training examples seen')\n",
    "plt.ylabel('negative log likelihood loss')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9cdf5f29",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "examples = enumerate(test_loader)\n",
    "batch_idx, (example_data, example_targets) = next(examples)\n",
    "with torch.no_grad():\n",
    "    output = network(example_data)\n",
    "fig = plt.figure()\n",
    "for i in range(6):\n",
    "    plt.subplot(2,3,i+1)\n",
    "    plt.tight_layout()\n",
    "    plt.imshow(example_data[i][0], cmap='gray', interpolation='none')\n",
    "    plt.title(\"Prediction: {}\".format(output.data.max(1, keepdim=True)[1][i].item()))\n",
    "    plt.xticks([])\n",
    "    plt.yticks([])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f9273f4",
   "metadata": {},
   "source": [
    "#优化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7e9619f",
   "metadata": {},
   "outputs": [],
   "source": [
    "continued_network = Net()\n",
    "continued_optimizer = optim.SGD(network.parameters(), lr=learning_rate, momentum=momentum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7a5abb4",
   "metadata": {},
   "outputs": [],
   "source": [
    "network_state_dict = torch.load('model.pth')\n",
    "continued_network.load_state_dict(network_state_dict)\n",
    "optimizer_state_dict = torch.load('optimizer.pth')\n",
    "continued_optimizer.load_state_dict(optimizer_state_dict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dcfb5bd1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 注意不要注释前面的“for epoch in range(1, n_epochs + 1):”部分，\n",
    "# 不然报错：x and y must be the same size\n",
    "# 为什么是“4”开始呢，因为n_epochs=3，上面用了[1, n_epochs + 1)\n",
    "for i in range(4, 9):\n",
    "    test_counter.append(i*len(train_loader.dataset))\n",
    "    train(i)\n",
    "    test()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f2ffeb93",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure()\n",
    "plt.plot(train_counter, train_losses, color='blue')\n",
    "plt.scatter(test_counter, test_losses, color='red')\n",
    "plt.legend(['Train Loss', 'Test Loss'], loc='upper right')\n",
    "plt.xlabel('number of training examples seen')\n",
    "plt.ylabel('negative log likelihood loss')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "pytorch"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
